package com.investmenttechnologyservices.datadictionary;

import java.util.Date;
import java.util.List;

import com.google.appengine.api.datastore.Key;
import com.investmenttechnologyservices.util.DateUtil;

public enum FieldType {
	
	LONG(new LongConvertor()), 
	DOUBLE(new DoubleConvertor()), 
	STRING(new StringConvertor()), 
	DATE(new DateConvertor()), 
	DATETIME(new DateTimeConvertor()), 
	BOOL(new BoolConvertor()),
	KEY(new KeyConvertor()),
	ENUM(new EnumConvertor()),
	ARRAYSTR(new ArrayOfStringsConvertor()),
	ARRAYLONG(new ArrayOfLongConvertor()),
	CURRENCY(new CurrencyConvertor());
	
	private static interface Convertor {
		Object stringToValue(String str);
		String valueToString(Object value);
	}
	
	private FieldType(Convertor convertor) {
		this.convertor = convertor;
	}
	
	private static char QUOTES = '\"';
	
	private static class LongConvertor implements Convertor {
		@Override public Object stringToValue(String str) { return Long.parseLong(str); }
		@Override public String valueToString(Object value) { return value.toString(); }
	}
	private static class DoubleConvertor implements Convertor {
		@Override public Object stringToValue(String str) { return Double.parseDouble(str); }
		@Override public String valueToString(Object value) { return value.toString(); }
	}
	private static class StringConvertor implements Convertor {
		@Override public Object stringToValue(String str) { return str; }
		@Override public String valueToString(Object value) { return QUOTES+(String)value+QUOTES; }
	}
	private static class DateConvertor implements Convertor {
		@Override public Object stringToValue(String str) { return DateUtil.parseDate(str); }
		@Override public String valueToString(Object value) { return QUOTES+DateUtil.toDateString((Date) value)+QUOTES; }
	}
	private static class DateTimeConvertor implements Convertor {
		@Override public Object stringToValue(String str) { return DateUtil.parseDateTime(str); }
		@Override public String valueToString(Object value) { return QUOTES+DateUtil.toDateTimeString((Date) value)+QUOTES; }
	}
	private static class BoolConvertor implements Convertor {
		@Override public Object stringToValue(String str) { return Boolean.parseBoolean(str); }
		@Override public String valueToString(Object value) { return value.toString(); }
	}
	private static class KeyConvertor implements Convertor {
		@Override public Object stringToValue(String str) { return null; }
		@Override public String valueToString(Object value) { 
			Key key = (Key)value;
			if (key.isComplete()) {
				String name = key.getName();
				if (name != null) {
					return QUOTES+name+QUOTES;
				} else {
					Long id = key.getId();
					return id.toString();
				}
			}
			return null;
		}
	}
	private static class EnumConvertor implements Convertor {
		@Override public Object stringToValue(String str) { return null; }
		@SuppressWarnings("rawtypes")
		@Override public String valueToString(Object value) {
			String str;
			if (value instanceof Enum) {
				str = ((Enum)value).name();
			} else if (value instanceof String) {
				str = (String)value;
			} else {
				throw new IllegalStateException();
			}
			return QUOTES+str+QUOTES;
		}
	}
	private static class CurrencyConvertor implements Convertor {
		@Override public Object stringToValue(String str) { return null; }
		@Override public String valueToString(Object value) { return null; }
	}
	private static class ArrayOfStringsConvertor implements Convertor {
		@Override public Object stringToValue(String str) { return null; }
		@Override public String valueToString(Object value) { 
			@SuppressWarnings("unchecked")
			List<String> arr = (List<String>)value;
			if (arr != null) {
				return QUOTES+arr.toString()+QUOTES;
			}
			return null;
		}
	}
	private static class ArrayOfLongConvertor implements Convertor {
		@Override public Object stringToValue(String str) { return null; }
		@Override public String valueToString(Object value) { 
			@SuppressWarnings("unchecked")
			List<Long> arr = (List<Long>)value;
			if (arr != null) {
				return QUOTES+arr.toString()+QUOTES;
			}
			return null;
		}
	}
	
	private final Convertor convertor;
	
	public Object stringToValue(String strValue) {
		return convertor.stringToValue(strValue);
	}
	public String valueToString(Object value) {
		return convertor.valueToString(value);
	}
}
